package com.kuangjia.boss.commonSafety.certificateAuthentication.verify;

import cn.hutool.system.OsInfo;
import cn.hutool.system.SystemUtil;
import com.kuangjia.boss.commonSafety.certificateAuthentication.controller.CreatorLicenseController;
import com.kuangjia.boss.commonSafety.certificateAuthentication.info.AbstractServerInfos;
import com.kuangjia.boss.commonSafety.certificateAuthentication.info.LinuxServerInfos;
import com.kuangjia.boss.commonSafety.certificateAuthentication.info.MacOsServerInfos;
import com.kuangjia.boss.commonSafety.certificateAuthentication.info.WindowsServerInfos;
import com.kuangjia.boss.commonSafety.certificateAuthentication.model.LicenseCheckModel;
import com.kuangjia.boss.commonSafety.certificateAuthentication.model.LicenseCreatorParam;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @author sixiaojie
 * @date 2021-05-25-15:42
 */
@Slf4j
@Component
public class LicenseCheckListener implements CommandLineRunner {
    /**
     * 证书subject
     */
    private String subject = "license";

    /**
     * 公钥别称
     */
    private String publicAlias = "publickey";

    /**
     * 密钥别称
     */
    private String privateAlias = "privatekey";

    /**
     * 访问公钥库的密码
     */
    private String storePass = "hsgk010";

    /**
     * 密钥密码（需要妥善保管，不能让使用者知道）
     */
    private String keyPass = "hsgk010";

    /**
     * 证书生成路径
     */
    @Value("${license.licensePath}")
    private String licensePath;


    @Value("${license.start}")
    private String start;

    @Value("${licenseTime}")
    private int licenseTime;


    /**
     * 密钥库存储路径
     */
    @Value("${license.publicKeysStorePath}")
    private String publicKeysStorePath;

    /**
     * 密钥库存储路径
     */
    @Value("${license.privateKeysStorePath}")
    private String privateKeysStorePath;


    /**
     * zip生成路径
     */
    @Value("${license.zipPath}")
    private String zipPath;


    /**
     * 是否需要验证授权
     */
    @Value("${isAuth:1}")
    private String isAuth;


    @Override
    public void run(String... args) throws Exception {
        log.info("++++++++ 授权监听器 已经执行 ++++++++");
        if (isAuth.equals("0")) {
            log.info("++++++++ 无需授权 ++++++++");
            return;
        }


        if ("1".equals(start)) {
            if (StringUtils.isNotBlank(licensePath)) {
                log.info("++++++++ 开始安装证书 ++++++++");
                if (new File(licensePath).exists()) {
                    if (!new File(publicKeysStorePath).exists()) {
                        log.info("找不到公钥文件");
                        System.exit(0);
                    }
                    LicenseVerifyParam param = new LicenseVerifyParam();
                    param.setSubject(subject);
                    param.setPublicAlias(publicAlias);
                    param.setStorePass(storePass);
                    param.setLicensePath(licensePath);
                    param.setPublicKeysStorePath(publicKeysStorePath);
                    LicenseVerify licenseVerify = new LicenseVerify();
                    //安装证书
                    licenseVerify.install(param);
                    log.info("++++++++ 证书安装结束 ++++++++");
                } else {
                    log.info("++++++++ 找不到license证书文件 ++++++++");
                    log.info("++++++++ 正在生成需要的授权文件 ++++++++");
                    LicenseCreatorParam param = new LicenseCreatorParam();
                    param.setKeyPass(keyPass);
                    param.setStorePass(storePass);
                    param.setLicensePath(licensePath);
                    param.setSubject(subject);
                    param.setPrivateKeysStorePath(privateKeysStorePath);
                    param.setPrivateAlias(privateAlias);
                    OsInfo osInfo = SystemUtil.getOsInfo();
                    AbstractServerInfos abstractServerInfo;
                    if (osInfo.isWindows()) {
                        abstractServerInfo = new WindowsServerInfos();
                    } else {
                        if (osInfo.isMac()) {
                            abstractServerInfo = new MacOsServerInfos();
                        } else {
                            abstractServerInfo = new LinuxServerInfos();
                        }
                    }
                    LicenseCheckModel infos = abstractServerInfo.getServerInfos();
                    param.setLicenseCheckModel(infos);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date());
                    //校验license时间
                    if (licenseTime == 0) {
                        log.info("+++++++请在配置文件中配置licenseTime+++++++");
                        System.exit(0);
                    }
                    calendar.add(Calendar.MONTH, licenseTime);
                    param.setExpiryTime(calendar.getTime());
                    Map<String, Object> resultMap = new CreatorLicenseController().generateLicense(param);
                    if (resultMap.get("result").equals("ok")) {
                        log.info("+++++++待授权文件生成成功，正在打压缩包+++++++");
                        //如果存在zip就删除重新生成
                        if (new File(zipPath).exists()) {
                            new File(zipPath).delete();
                        }
                        ZipFile zipFile = new ZipFile(zipPath);
                        ZipParameters parameters = new ZipParameters();
                        //打包密码
                        String pwd = "010";
                        if (null == infos.getMacAddress() || infos.getIpAddress().isEmpty()) {
                            log.error("+++++++无法获取信息+++++++");
                        } else {
                            String ip = infos.getIpAddress().get(0);
                            pwd = ip.replace(".", "");
                        }
                        parameters.setEncryptFiles(true);
                        parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
                        parameters.setPassword(pwd);
                        //重命名证书(刚生成肯定存在)
                        File licence = new File(licensePath);
                        String rename = RandomStringUtils.randomAlphabetic(5);//生成8位字符串
                        File reLicence = new File(rename);
                        licence.renameTo(reLicence);
                        zipFile.addFile(reLicence, parameters);
                        log.info("+++++++打包成功++++++");
                        reLicence.delete();
                    }
                    System.exit(0);
                }

            } else {
                log.info("++++++++ 未配置License证书 ++++++++");
                System.exit(0);
                // throw new RuntimeException("++++++++ 未配置License证书 ++++++++");
            }
        }
    }
}
